package br.com.dallasmotopecas.venda.dashboard.controller;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.faces.context.ExternalContext;

import br.com.dallasmotopecas.comum.cliente.controller.ClienteAbcController;
import br.com.dallasmotopecas.comum.cliente.controller.ClienteAssociadoController;
import br.com.dallasmotopecas.comum.cliente.controller.ClienteController;
import br.com.dallasmotopecas.comum.cliente.controller.ClienteDadosController;
import br.com.dallasmotopecas.comum.cliente.vo.ClienteAbcVo;
import br.com.dallasmotopecas.comum.cliente.vo.ClienteDadosGeralVo;
import br.com.dallasmotopecas.comum.cliente.vo.ClienteDadosVo;
import br.com.dallasmotopecas.comum.cliente.vo.ClienteVo;
import br.com.dallasmotopecas.util.controller.AbstractController;
import br.com.dallasmotopecas.util.converter.ConverterNumeros;
import br.com.dallasmotopecas.util.exception.ClasseNaoEncontradaException;
import br.com.dallasmotopecas.util.exception.ConexaoException;
import br.com.dallasmotopecas.util.exception.ConsultarObjetoException;
import br.com.dallasmotopecas.util.exception.ListarObjetoException;
import br.com.dallasmotopecas.util.exception.NumeroFormatoInvalidoException;

public class VendaDashBoardController extends AbstractController
{
	public VendaDashBoardController(Connection connection) throws ConexaoException
	{
		super(connection);
	}
	
	public VendaDashBoardController(ExternalContext externalContext) throws ClasseNaoEncontradaException, ConexaoException
	{
		super(externalContext);
	}

	public void carregarClientes(final List<ClienteDadosVo> listaClienteDados, final ClienteDadosVo clienteDadosVo, final ClienteDadosGeralVo clienteDadosGeralVo, List<ClienteVo> listaClienteSemMovimento) throws ListarObjetoException, ConexaoException, ConsultarObjetoException, NumeroFormatoInvalidoException
	{	
		ClienteDadosController clienteDadosController = null;
		List<ClienteVo> listaCliente = null;
		try
		{
			listaClienteDados.clear();
			clienteDadosController = new ClienteDadosController(getConnection());
			clienteDadosController.carregarListaDados(listaClienteDados, clienteDadosVo);
			listaCliente = new ArrayList<ClienteVo>();
			carregarClienteComAssociados(listaCliente, clienteDadosVo.getClienteVo());
			carregarDadosClienteComAssociados(listaClienteDados, listaCliente,listaClienteSemMovimento);
			Collections.sort(listaClienteDados);
			Collections.reverse(listaClienteDados);
			classificacaoABC(listaClienteDados, clienteDadosGeralVo);
		}
		catch(ListarObjetoException e)
		{
			throw e;
		}
		catch (ConexaoException e)
		{
			throw e;
		}
		catch (ConsultarObjetoException e)
		{
			throw e;
		}
		finally
		{
			clienteDadosController = null;
		}
	}
	
	private void classificacaoABC(final List<ClienteDadosVo> listaClienteDados, final ClienteDadosGeralVo clienteDadosGeralVo) throws ConexaoException, ConsultarObjetoException, NumeroFormatoInvalidoException
	{
		ClienteAbcController clienteAbcController = null;
		ClienteAbcVo clienteAbcVo = null;
		double valorTotal = 0, percentualAcumulado = 0, valorTotalCurvaA = 0, valorTotalCurvaB = 0, valorTotalCurvaC = 0;
		int qtdTotalCurvaA = 0, qtdTotalCurvaB = 0, qtdTotalCurvaC = 0, qtdTotalClientes = 0;
		try
		{
			if (listaClienteDados != null && clienteDadosGeralVo != null)
			{
				clienteAbcController = new ClienteAbcController(getConnection());
				clienteAbcVo = new ClienteAbcVo();
				clienteAbcController.consultarClienteAbc(clienteAbcVo);
				
				for (int i = 0; i < listaClienteDados.size(); i++)
				{
					valorTotal += listaClienteDados.get(i).getValorCompraTotal();
				}
				
				
				
				for (int i = 0; i < listaClienteDados.size(); i++)
				{
					percentualAcumulado += listaClienteDados.get(i).getValorCompraTotal() * 100 / valorTotal;
					
					if (percentualAcumulado < (clienteAbcVo.getPercentualCurvaA() + clienteAbcVo.getMargemErroCurvaA()))
					{
						listaClienteDados.get(i).setClassificacao("A");
						listaClienteDados.get(i).setCorClassificacao("#006400");
						valorTotalCurvaA += listaClienteDados.get(i).getValorCompraTotal();
						++qtdTotalCurvaA;
					} 
					else if (percentualAcumulado < (clienteAbcVo.getPercentualCurvaB() + clienteAbcVo.getMargemErroCurvaB() + clienteAbcVo.getPercentualCurvaA()))
					{
						listaClienteDados.get(i).setClassificacao("B");
						listaClienteDados.get(i).setCorClassificacao("#FFA500");
						valorTotalCurvaB += listaClienteDados.get(i).getValorCompraTotal();
						++qtdTotalCurvaB;
					} 
					else
					{
						listaClienteDados.get(i).setClassificacao("C");
						listaClienteDados.get(i).setCorClassificacao("#FF0000");
						valorTotalCurvaC += listaClienteDados.get(i).getValorCompraTotal();
						++qtdTotalCurvaC;
					}
					++qtdTotalClientes;
				}
				clienteDadosGeralVo.setQtdVendaGeral(ConverterNumeros.converteDoubleParaBigDecimal(2, valorTotal).doubleValue());
				clienteDadosGeralVo.setQtdValorCurvaA(ConverterNumeros.converteDoubleParaBigDecimal(2, valorTotalCurvaA).doubleValue());
				clienteDadosGeralVo.setQtdValorCurvaB(ConverterNumeros.converteDoubleParaBigDecimal(2, valorTotalCurvaB).doubleValue());
				clienteDadosGeralVo.setQtdValorCurvaC(ConverterNumeros.converteDoubleParaBigDecimal(2, valorTotalCurvaC).doubleValue());
				clienteDadosGeralVo.setQtdClienteCurvaA(qtdTotalCurvaA);
				clienteDadosGeralVo.setQtdClienteCurvaB(qtdTotalCurvaB);
				clienteDadosGeralVo.setQtdClienteCurvaC(qtdTotalCurvaC);
				clienteDadosGeralVo.setQtdTotalCliente(qtdTotalClientes);
			}
		}
		catch(ConexaoException e)
		{
			throw e;
		}
		catch (ConsultarObjetoException e)
		{
			throw e;
		}
		catch (NumeroFormatoInvalidoException e)
		{
			throw e;
		}
		finally
		{
			clienteAbcController = null;
			clienteAbcVo = null;
		}
	}
	
	
	private void carregarClienteComAssociados(final List<ClienteVo> listaCliente, final ClienteVo clienteVo) throws ConexaoException, ListarObjetoException
	{
		ClienteController clienteController = null;
		ClienteAssociadoController clienteAssociadoController = null;
		try
		{
			if (listaCliente != null && clienteVo != null)
			{
				listaCliente.clear();
				clienteController = new ClienteController(getConnection());
				clienteController.listarCliente(listaCliente, clienteVo);
				
				clienteAssociadoController = new ClienteAssociadoController(getConnection());
				
				for (int i = 0; i < listaCliente.size(); i++)
				{
					clienteAssociadoController.carregarListaAssociados(listaCliente.get(i).getClienteAssociados(), listaCliente.get(i));
					listaCliente.get(i).getClienteAssociados().add(0, listaCliente.get(i));
				}
			}
		}
		catch(ConexaoException e)
		{
			throw e;
		}
		catch (ListarObjetoException e)
		{
			throw e;
		}
		finally
		{
			clienteController = null;
			clienteAssociadoController = null;
		}
	}
	
	private void carregarDadosClienteComAssociados(final List<ClienteDadosVo> listaClienteDados, final List<ClienteVo> listaCliente, List<ClienteVo> listaClienteSemMovimento) throws NumeroFormatoInvalidoException
	{
		List<ClienteDadosVo> listaNovaDados = null;
		List<ClienteVo> listaClienteAssociado = null;
		ClienteDadosVo clienteDadosVo = null;
		boolean isClienteSemMovimento = false;
		double valor = 0;
		try
		{
			listaNovaDados = new ArrayList<ClienteDadosVo>();
			listaClienteAssociado = new ArrayList<ClienteVo>();
			for (int i = 0; i < listaCliente.size(); i++)
			{
				valor = 0;
				if (listaClienteAssociado.contains(listaCliente.get(i)))
					continue;
				
				for (int j = 0; j < listaCliente.get(i).getClienteAssociados().size(); j++)
				{
					if (listaClienteAssociado.contains(listaCliente.get(i).getClienteAssociados().get(j)))
						continue;
					
					if (j == 0)
					{
						clienteDadosVo = new ClienteDadosVo();
						clienteDadosVo.setClienteVo(listaCliente.get(i).getClienteAssociados().get(j));
					}
					
					for (int k = 0; k < listaClienteDados.size(); k++)
					{	
						if (listaCliente.get(i).getClienteAssociados().get(j).getId() == listaClienteDados.get(k).getClienteVo().getId())
						{
							valor += listaClienteDados.get(k).getValorCompraTotal();
							listaClienteAssociado.add(listaCliente.get(i).getClienteAssociados().get(j));
							clienteDadosVo.getClienteVo().getDadosCliente().add(listaClienteDados.get(k));
						}
						else
						{
							listaClienteAssociado.add(listaCliente.get(i).getClienteAssociados().get(j));
						}
					}
				}
				if (valor > 0)
				{
					clienteDadosVo.setValorCompraTotal(ConverterNumeros.converteDoubleParaBigDecimal(2, valor).doubleValue());
					listaNovaDados.add(clienteDadosVo);
				}
			}
			
			for (int i = 0; i < listaCliente.size(); i++)
			{
				for (int j = 0; j < listaNovaDados.size(); j++)
				{
					isClienteSemMovimento = true;
					
					if (listaCliente.get(i).getId() == listaNovaDados.get(j).getClienteVo().getId())
					{
						isClienteSemMovimento = false;
					}
				}
				
				if (isClienteSemMovimento)
					listaClienteSemMovimento.add(listaCliente.get(i));
			}
			
			listaClienteDados.clear();
			listaClienteDados.addAll(listaNovaDados);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			listaNovaDados = null;
			listaClienteAssociado = null;
			clienteDadosVo = null;
		}
	}
}
